// Object.assgin polyfill
if (typeof Object.assign != 'function') {
    // Must be writable: true, enumerable: false, configurable: true
    Object.defineProperty(Object, "assign", {
        value: function assign(target, varArgs) { // .length of function is 2
            'use strict';
            if (target == null) { // TypeError if undefined or null
                throw new TypeError('Cannot convert undefined or null to object');
            }
            var to = Object(target);
            for (var index = 1; index < arguments.length; index++) {
                var nextSource = arguments[index];

                if (nextSource != null) { // Skip over if undefined or null
                    for (var nextKey in nextSource) {
                        // Avoid bugs when hasOwnProperty is shadowed
                        if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
                            to[nextKey] = nextSource[nextKey];
                        }
                    }
                }
            }
            return to;
        },
        writable: true,
        configurable: true
    });
}

// 正则验证字典
var $regExp = {
    $phone: /^1[3456789]\d{9}$/,
    $email: /^([A-Za-z0-9_\-.])+@([A-Za-z0-9_\-.])+\.([A-Za-z]{2,4})$/,
    $pass: /^[A-Za-z0-9]{8,16}$/,
    $realName: /^[\u4E00-\u9FA5\uf900-\ufa2d·s]{2,20}$/,
    $ID: /^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|31)|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}([0-9]|x|X)$/
}

// 浅拷贝
var $copy = Object.assign;
/* 
  //严格类型判断
  $toClass(key:any);
*/
function $toClass(key) {
  return Object.prototype.toString.call(key).split(" ")[1].replace("]", "");
}
/* 
  //类型判断函数 
  $isType(target:any,type:any);
*/
function $isType(target, type) {
  var targetType = $toClass(target);
  return targetType === type;
}
/* 
  // 判断对象是否具有某个属性
  $hasOwn(obj:Object,key:String);
*/
function $hasOwn(obj,key){
  if( obj && $isType(obj,"Object") ){
    return Object.hasOwnProperty.call(obj,key);
  }else{
    throw new Error("the obj params classType is not a Object");
  }
}
/* 
  //字符串除去空格 
  $trimAll(str:String);
*/
function $trimAll(str) {
  if (str) {
      return str.replace(/\s/gm, "");
  } else {
      return str;
  }
}


// 路由
/* 
    使用方法
    $url(opts:String|Object [,ass:String|Object]);
    $url("./b.html?name=123&age=15");
    $url("./b",{ name：123,age:15 });
    $url({
        url:"./b"
        ,options:"name=123&age=15" || { name:123,age:15 }
        ,replace: false || true  // 当replace为 true的时候  相当于  window.location.replace
    });
    
*/
function $url(opts, ass) {
    if (opts) {
        var assOpts = {
            html: false
        };
        var optsType = $toClass(opts);
        var upCopy = function (urlstr) {
            var strArr = urlstr.split("?");
            var url = strArr[0];
            var options = strArr[1];
            assOpts.url = url;
            if (options) {
                assOpts.options = options;
            }
        };
        if (optsType == "String") {
            upCopy(opts);
        } else if (optsType == "Object") {
            $copy(assOpts, opts);
            upCopy(opts.url);
        } else {
            throw new TypeError("the opts type must be String or Object")
        }

        var url = assOpts.url;
        if (url && (url = $trimAll(url))) {
            // 如果第二个参数存在 赋值给options
            if (ass) {
                assOpts.options = ass;
            }
            var sezOpts = "";
            var options = assOpts.options;
            // 判断options是否存在
            if (options) {
                //严格类型判断
                var opType = $toClass(options);
                // 对象类型进行字符串序列化
                if (opType == 'Object') {
                    var optKeysArr = Object.keys(options);
                    var optKeysLen = optKeysArr.length;
                    // 如果对象有可枚举属性 忽略原型
                    if (optKeysLen) {
                        var keysArr = [];
                        optKeysArr.forEach(function (va) {
                            // 值
                            var val = options[va];
                            // 符号 -- 拼接符号
                            keysArr.push(va + "=" + val);
                        });
                        sezOpts = keysArr.join("&");
                    }

                } else if (opType == 'String') {
                    sezOpts = $trimAll(options);
                } else {
                    throw new TypeError('the options must be Object or String');
                }
                if (sezOpts) {
                    sezOpts = "?" + sezOpts;
                }
            }

            var sezUrl;
            var html = assOpts.html;
            var replace = assOpts.replace;
            if (html && !/\.html$/.test(url)) {
                sezUrl = url + ".html";
            } else {
                sezUrl = url;
            }
            location[replace ? 'replace' : 'assign'](sezUrl + sezOpts);

        } else {
            throw new ReferenceError("the opts url is undefined");
        }
    } else {
        throw new ReferenceError("the opts params  must be required");
    }
    if (event) {
        event.stopPropagation(), event.preventDefault();
    }
}
// 路由
/* 
    默认返回一层 相当于返回按钮
    $back( [ leve:Number ] )
*/
function $back(leve) {
    if( leve !== undefined ){ leve = -1 };
    history.go(leve);
    if (event) {
        event.stopPropagation(), event.preventDefault();
    }
}
// 路由参数
/* 
    解析路由参数
    默认解析当前路由
    主动调用
    $options([opts:String]);
    $options( "b.html?name=123&age=15" );
    返回一个解析过的对象类型  如果参数不存在  则打印一个警告  返回 undefined
*/
function $options(opts) {
    var url;
    if (opts) {
        if (typeof opts == "string") {
            url = $trimAll(opts);
        } else {
            throw new TypeError("the opts type must be String");
        }
    } else {
        url = location.href;
    }
    var search = url.split("?")[1];
    if (search) {
        var options = {};
        search.split("&").forEach(function (va) {
            if (va) {
                var splitArr = va.split("=");
                var key = splitArr[0];
                var val = splitArr[1];
                options[key] = val;
            }
        });
        return options;
    } else {
        console.warn("the url options is null");
    }
}

/* 
    上传图片
    $uploadImg(FileObject);
    主动调用
    <input type="file" accept="image/*" id="fileNode" />

    $("#fileNode").change(function(event){
        // 单张图片
        let baseSrc = uploadImg( event.target.files[0] );
        console.log( baseSrc );

        // 多选图片
        // Array.prototype.forEach.call( event.target.files,function(res)=>{
        //     let baseSrc = uploadImg( res );
        //     console.log( baseSrc );
        // });

        // es6 Array.from( event.target.files ).forEach ...;
    });
*/
var $FileReader = new FileReader();
function $uploadImg(file, suc) {
    $FileReader.readAsDataURL(file);
    try {
        $FileReader.onload = function (res) {
            suc && typeof suc == "function" && suc(res.target.result);
        }
    } catch (err) {
        console.error(err);
    }
}

/*
	复制文本到剪切板
*/

function $clip( copyText , callback ){
	var doc = document;
	var body = doc.body;
	var insertInput = doc.createElement("input");
	insertInput.setAttribute("style","posttion:fixed;left:-100%;");
	if( copyText && typeof copyText === "string" ){
		insertInput.value = copyText;
	}else{
		throw Error("the params copyText type must be vaild String");
	}
	
	body.appendChild( insertInput );
	try{
		insertInput.select();
		doc.execCommand("copy");
		if( callback && typeof callback === "function" ){
			callback();
		}
		body.removeChild( insertInput );
	}catch(err){
		
		throw Error( err );
	}
}

/* 
    绑定全局 路由
    <nav data-back> 返回 </nav>
    <nav data-url="b" data-options="route=a&next=b"> 跳转到b页面面 </nav>
*/
try {
    if ((jQuery && jQuery == $ && 'function' == typeof jQuery)) {
        $(function () {
            var body = $('body');
            body.on('click', '[data-url]', function () {
                $url($(this).data());
            });
            body.on("click", '[data-back]', function () {
                $back(-1);
            });
        });
    }
} catch (error) {
    console.warn(error);
}